package org.interfaceadaptation.test.notnull;

public class CompoundVerifier implements Verifier {

	private Verifier entryPoint;

	private CompoundInstrospectorRegister compoundInstrospectorRegister = CompoundInstrospectorRegister
			.getInstance();

	public CompoundVerifier(Verifier entryPoint) {
		this.entryPoint = entryPoint;
	}

	@Override
	public boolean verify(Object element) {
		CompoundInstrospector compoundInstrospector = getCompoundInstrospector(element);
		if (compoundInstrospector != null) {
			return compoundVerify(compoundInstrospector, element);
		} else {
			return false;
		}
	}

	private boolean compoundVerify(CompoundInstrospector compoundInstrospector,
			Object element) {

		if (verifyEmptyness(compoundInstrospector, element)) {
			return true;
		}
		for (Object subElement : compoundInstrospector.getSubElements(element)) {
			if (! entryPoint.verify(subElement)) {
				return false;
			}
		}
		return true;
	}

	private boolean verifyEmptyness(CompoundInstrospector compoundInstrospector,
			Object element) throws AssertionDeepNotNullError {
		if (compoundInstrospector.numSubElements(element) == 0) {
			if (compoundInstrospector.emptyIsNull()) {
				throw new AssertionDeepNotNullError();
			} else {
				return true;
			}
		}
		else {
		  return false;
		}
	}

	protected void setCompoundInstrospectorRegister(
			CompoundInstrospectorRegister compoundInstrospectorRegister) {
		this.compoundInstrospectorRegister = compoundInstrospectorRegister;
	}

	private CompoundInstrospector getCompoundInstrospector(Object element) {
		return compoundInstrospectorRegister
				.getCompoundInstrospectorFor(element);
	}

}
